package edu.ecut.cs.ai.search;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import edu.ecut.cs.ai.status.Status;

public abstract class SearchAlogithm {
	int MaxSteps;
	int steps;
	int done;
	Status currentStatus;

	List<Status> extendedStatuses;
	List<Status> unextendedStatuses;	
	
	public abstract void updateTree(Status child);
	
	public void search() {
		List<Status>  children;
		while (!currentStatus.isTargetStatus()) {
			System.out.println("step " + steps +": " + extendedStatuses.size() + ", " + unextendedStatuses.size());
			System.out.println(currentStatus.toString());
			children = currentStatus.getChildren();
			for (Status child: children) {
				if (findStatus(child, extendedStatuses) == -1) {
					updateTree(child);
				}
			}			
			steps++;			
						
			if (unextendedStatuses.size() > 0) {
				if (steps < MaxSteps) {
					currentStatus = unextendedStatuses.remove(0);
					extendedStatuses.add(currentStatus);
				} else {
					done = 0;
					break;
				}
			} else {
				done = -1;
				break;
			}
		}		
	}
	
	public void init(Status s) {
		extendedStatuses = new ArrayList<Status>();
		unextendedStatuses = new ArrayList<Status>();	
		s.getInitStatus(false);
		currentStatus = s;
		extendedStatuses.add(currentStatus);
		done = 1;
		steps = 0;		
	}
	
	public void outputSolution(String fileName) throws IOException {
		Stack<Status> solution = new Stack<Status>();
		Status parent = currentStatus;
		while (parent != null) {
			solution.push(parent);
			parent = parent.getParent();
		}

		String answer = null;
		File f = new File(fileName);
		Writer w = new FileWriter(f);
		switch (done) {
			case 1 -> answer = "Task is done in " + steps + " steps. Length of the solution is " + solution.size() + ".\n";
			case -1 -> answer = "Task is unresolved. Search space is exhausted in " + steps + " steps. Length of the path to final status is " + solution.size() + ".\n";
			case 0 -> answer = "Task is unresolved in " + MaxSteps + " steps. Length of the path to final status is " + solution.size() + ".\n";
		}
		int i = 0;
		Status s;
		while (!solution.empty()) {
			s = solution.pop();
			answer += "S_"+i+": " + s.toString();
			i++;
		}
		w.write(answer);
		w.close();
		
		System.out.println(answer);
	}
	
	public static int findStatus(Status s, List<Status> l) {
		int r = -1;
		Status x;
		for (int i = 0; i < l.size(); i++) {
			x = l.get(i);
			if (s.sameAs(x)) {
				r = i;
				break;
			} 
		}
		return r;
	}

}
